﻿/*
 * Copyright (c) Huawei Technologies Co., Ltd. 2012-2018. All rights reserved.
 * Description:
 * Author: 辛爱国 x30005137
 * Create: 2020-07-28
 * Notes: 无
 */
#include "toastdialog.h"
#include <QGraphicsDropShadowEffect>
#include <QFontMetrics>
#include <QDesktopWidget>
#include <QDebug>
#include <qapplication.h>
#include <qscreen.h>
#include <qstyle.h>

static constexpr int MAX_RETRY_TIMES = 6;

ToastDialog::ToastDialog(QWidget *parent) : HWDialog(parent)
{
    setupUi(this);
    setWindowFlags(Qt::FramelessWindowHint | Qt::Dialog | Qt::WindowStaysOnTopHint);
    this->setAttribute(Qt::WA_TranslucentBackground);

    QGraphicsDropShadowEffect *shadow_effect = new QGraphicsDropShadowEffect(this);
    shadow_effect->setOffset(0, 0);
    shadow_effect->setColor(Qt::gray);
    shadow_effect->setBlurRadius(10);   // 阴影设置半径10
    this->widgetWindow->setGraphicsEffect(shadow_effect);


    QFontMetrics pfont(this->labelTitle->font());
    int wid = pfont.boundingRect(this->labelTitle->text()).width();
    this->labelTitle->setFixedWidth(wid + 12);  // 文本长度增加12

    this->m_wait = new QTimer(this);
    this->m_wait->setInterval(200);       // 定时器设置 200
    connect(this->m_wait, SIGNAL(timeout()), this, SLOT(updateWait()));

    this->m_keepalive_timer = new QTimer(this);
    this->m_keepalive_timer->setInterval(5000);  // 定时器设置 5000
    connect(this->m_keepalive_timer, SIGNAL(timeout()), this, SLOT(handleKeepAlive()));
    this->m_keepalive_timer->start();

    this->m_retry_timer = new QTimer(this);
    this->m_retry_timer->setSingleShot(true);                       /* 执行一次 */
    this->m_retry_timer->setInterval(3000);     // 定时器设置 3000
    connect(this->m_retry_timer, SIGNAL(timeout()), this, SLOT(handleConnectRetry()));

    this->m_timeout_timer = new QTimer(this);
    this->m_timeout_timer->setSingleShot(true);                     /* 执行一次 */
    this->m_timeout_timer->setInterval(2000);        // 定时器设置 2000
    connect(this->m_timeout_timer, SIGNAL(timeout()), this, SLOT(handleConnectTimeout()));

    this->m_sharing_timeout_timer = new QTimer(this);
    this->m_sharing_timeout_timer->setSingleShot(true);             /* 执行一次 */
    this->m_sharing_timeout_timer->setInterval(10 * 1000);          // 定时器设置 10 * 1000 ms
    connect(this->m_sharing_timeout_timer, SIGNAL(timeout()), this, SLOT(handleSharingTimeout()));

    this->setWindowTitle("IdeaShare Key");
    saveChildrenInfo();
   
}
ToastDialog::~ToastDialog() {}
void ToastDialog::resizeEvent(QResizeEvent *event)
{
    HWDialog::resizeEvent(event);
    windowReturn();
}
void ToastDialog::on_pushButtonExit_clicked()
{
    stop_retry_timer();
    stop_timeout_timer();
    m_wait->stop();
    this->hide();
}
void ToastDialog::updateWait()
{
    QMatrix matrix;
    QPixmap image_wait(":/image/images/31.png");

    matrix.rotate(90 * this->m_spinIndex);            // 旋转90°
    image_wait = image_wait.transformed(matrix, Qt::FastTransformation);
    this->labelPictureConnect->setPixmap(image_wait.transformed(matrix, Qt::FastTransformation));
    this->m_spinIndex > 2 ? this->m_spinIndex = 0 : this->m_spinIndex++;          // 0 1 2 3 转一圈
}

void ToastDialog::handleConnect()
{
    qDebug() << "handleConnect";
    stop_retry_timer();
    showConnecting();
    m_errorCount = 0;
    start_timeout_timer();
    qDebug() << "ideashare key::terminal::connect";
}
void ToastDialog::handleConnectBusy()
{
    qDebug() << "handleConnectBusy";
    stop_timeout_timer();
    this->m_wait->stop();
    start_retry_timer();
    showConnectBusy();
}
void ToastDialog::handleConnectRetryMax()
{
    qDebug() << "handleConnectRetryMax";
    this->m_wait->stop();
    this->labelStatus->setText(tr("Failed"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(tr("The number of connections has reached the maximum."));
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/30.png"));
    this->show();
    qDebug() << "m_errorCount :" << m_errorCount << " set zero";
    m_errorCount = 0;
}

void ToastDialog::handleConnectSuccess()
{
    qDebug() << "handleConnectSuccess";
    stop_retry_timer();
    stop_timeout_timer();
    showConnectSuccess();
    qDebug() << "m_errorCount :" << m_errorCount << " set zero";
    m_errorCount = 0;
}

void ToastDialog::handleConnectFailed()
{
    stop_timeout_timer();
    if (m_errorCount >= MAX_RETRY_TIMES) {
        qDebug() << "handleConnectFailed";
        showConnectFiled();
        m_errorCount = 0;
    }
    qDebug() << "Reconnect............";
    start_retry_timer();
}

void ToastDialog::handleDisConnectAndRetry()
{
    qDebug() << "handleDisConnectAndRetry";
    this->m_wait->stop();
    showDisConnect();
    start_retry_timer();
    hideDisappearing(5000); // 5000 ms 渐变消失
}
void ToastDialog::handleDisConnectAndExit()
{
    qDebug() << "handleDisConnectAndExit";
    disconnect(this->m_retry_timer, SIGNAL(timeout()), this, SLOT(handleConnectRetry()));
    disconnect(this->m_timeout_timer, SIGNAL(timeout()), this, SLOT(handleConnectTimeout()));
    this->m_wait->stop();
    showDisConnect();
    closeDisappearing(5000); // 5000 ms 渐变消失
}

void ToastDialog::handleConnectTimeout()
{
    if (m_errorCount >= MAX_RETRY_TIMES) {
        qDebug() << "handleConnectTimeout";
        showConnectFiled();
        m_errorCount = 0;
    }
    start_retry_timer();
}
void ToastDialog::handleSharingTimeout()
{
    IDEASHARE_ERROR_ID errocde = IDEASHARE_ERROR_MULTICONNECT_TERMINAL_BUSY;
    showShareFiled(errocde);
}
void ToastDialog::handleConnectRetry()
{
    qDebug() << "handleConnectRetry";
    if (true) {
        qDebug() << "handleConnect";
        showConnecting();
        m_errorCount++;
        start_timeout_timer();
    } else {
        handleConnectRetryMax();
    }
}
void ToastDialog::handleKeepAlive()
{
    qDebug() << "send keep alive message...";
    //ideasharesdk::terminal::notifyKeepAlive();
}
void ToastDialog::hideDisappearing(int ms)
{
    if (m_isQuit) return;
    QPropertyAnimation *animation = new QPropertyAnimation(this, "windowOpacity");
    animation->setDuration(5000);
    animation->setStartValue(1);
    if (ms < 0) {
        animation->setEndValue(1);
    } else {
        animation->setEndValue(0);
        connect(animation, SIGNAL(finished()), this, SLOT(hide()));
    }
    qDebug() << "hideDisappearing";
    animation->start();
    qDebug() << "############################ hideDisappearing ####################";
    this->show();
}
void ToastDialog::closeDisappearing(int ms)
{
    m_isQuit = true;
    /* 慢慢消失的效果 */
    QPropertyAnimation *animation = new QPropertyAnimation(this, "windowOpacity");
    animation->setDuration(ms);
    animation->setStartValue(1);
    animation->setEndValue(0);
    animation->start();
    connect(animation, SIGNAL(finished()), this, SLOT(close()));
    // 效果显示完后关闭
    qDebug() << "############################ closeDisappearing ####################";
    this->show();
}

void ToastDialog::start_retry_timer()
{
    if (m_retry_timer->isActive() == true) {
        m_retry_timer->stop();
    }
    m_retry_timer->start();
}
void ToastDialog::stop_retry_timer()
{
    if (m_retry_timer->isActive() == true) {
        m_retry_timer->stop();
    }
}
void ToastDialog::start_timeout_timer()
{
    if (m_timeout_timer->isActive() == true) {
        m_timeout_timer->stop();
    }
    m_timeout_timer->start();
}
void ToastDialog::stop_timeout_timer()
{
    if (m_timeout_timer->isActive() == true) {
        m_timeout_timer->stop();
    }
}
void ToastDialog::start_sharing_timeout_timer()
{
    if (m_sharing_timeout_timer->isActive() == true) {
        m_sharing_timeout_timer->stop();
    }
    m_sharing_timeout_timer->start();
}
void ToastDialog::stop_sharing_timeout_timer()
{
    if (m_sharing_timeout_timer->isActive() == true) {
        m_sharing_timeout_timer->stop();
    }
}
void ToastDialog::windowReturn()
{
    QPoint pt = QApplication::screenAt(this->pos())->geometry().bottomRight();
    this->move(pt - this->rect().bottomRight() - QPoint(20, 50) * getCurrentRate(this));
}
void ToastDialog::showDisConnect()
{
    qDebug() << "showDisConnect";
    this->m_wait->stop();
    stop_sharing_timeout_timer();
    stop_retry_timer();
    this->labelStatus->setText(tr("Disconnected"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(tr("Please Reconnect IdeaShare Key"));
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/30.png"));
    windowReturn();
    qDebug() << "m_errorCount :" << m_errorCount << " set zero";
    m_errorCount = 0;
}
void ToastDialog::showConnectBusy()
{
    qDebug() << "showConnectBusy";
    this->labelStatus->setText(tr("Busy"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(tr("Please Reconnect IdeaShare Key"));
    windowReturn();
    hideDisappearing(5000); // 5000 ms 渐变消失
}
void ToastDialog::showConnecting()
{
    setBaseInfo(false);
    // 增加保护，如果辫子线未插入PC，此时直接提示并退出APP
//    if (!ideasharesdk::terminal::isInitSuccess()) {
//        handleDisConnectAndExit();
//        return;
//    }
    // 辫子线连接终端
    qDebug() << "ideashare key::terminal::connect";
//    ideasharesdk::terminal::keyConnect();
    this->labelStatus->setText(QObject::tr("Connecting"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(QObject::tr("Please Keep IdeaShare Key Connected"));
    this->m_wait->start();
    windowReturn();
    hideDisappearing(-1);
}
void ToastDialog::showConnectSuccess()
{
    this->m_wait->stop();
    setBaseInfo(false);
    this->labelStatus->setText(tr("Success"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(tr("Press the Smart Projector to project the screen."));
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/125.png"));
    windowReturn();
    hideDisappearing(-1);
}
void ToastDialog::showConnectFiled()
{
    this->m_wait->stop();
    stop_sharing_timeout_timer();
    setBaseInfo(false);
    /* 告知辫子线连接失败 */
//    ideasharesdk::terminal::notifyConnectFailed();
    this->labelStatus->setText(tr("Failed"));
    this->labelFailTip->setVisible(true);
    this->labelFailTip->setText(tr("Please Reconnect IdeaShare Key"));
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/30.png"));
    windowReturn();
    hideDisappearing(5000);
}
void ToastDialog::showSharing()
{
    setBaseInfo(true);
    start_sharing_timeout_timer();
    this->labelStatus->setText(tr("Sharing......"));
    this->labelFailTip->setVisible(false);
    this->m_wait->start();
    windowReturn();
    hideDisappearing(-1);
}
void ToastDialog::showShareSuccess()
{
    // 辫子线共享成功不再提示
    this->m_wait->stop();
    stop_sharing_timeout_timer();
    this->hide();
}
void ToastDialog::showShareStop()
{
    setBaseInfo(true);
    stop_sharing_timeout_timer();
    this->labelStatus->setText(tr("stop share"));
    this->labelFailTip->setVisible(false);
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/124.png"));
    windowReturn();
    hideDisappearing(5000); // 5000 ms 渐变消失
}
void ToastDialog::showShareFiled(IDEASHARE_ERROR_ID &toast)
{
    this->m_wait->stop();
    stop_sharing_timeout_timer();
    setBaseInfo(true);
    this->labelStatus->setText(tr("Share filed"));
    this->labelFailTip->setVisible(true);
//    this->labelFailTip->setText(strerrno(toast));
    this->labelPictureConnect->setPixmap(QPixmap(":/image/images/30.png"));
    windowReturn();
    hideDisappearing(5000); // 5000 ms 渐变消失
}

void ToastDialog::setBaseInfo(bool isshare)
{
    QPoint movePt = { 0, 0 };
    if (isshare) {
        this->labelWidPicture->setObjectName("labelWidPictureshare");
        movePt = QPoint(9, -14); // QPoint(9, -14)相对位移
    } else {
        this->labelWidPicture->setObjectName("labelWidPicture");
        movePt = QPoint(-15, -12); // QPoint(-15, -12)相对位移
    }
    QPoint centerPic = this->labelWidPicture->rect().center();
    this->labelPictureConnect->move(centerPic + movePt);
    this->labelWidPicture->style()->unpolish(this->labelWidPicture);
    this->labelWidPicture->style()->polish(this->labelWidPicture);
    this->labelWidPicture->update();
    this->labelPictureConnect->setScaledContents(true);
}
